/**
 * @file UP_PWM.c
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2023-05-12
 *
 * @copyright Copyright (c) 2023
 *
 * PWM频率=240 000 000 /( (pre+1) * (per+1) )
 */
#include "UP_PWM.h"
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "UP_config.h"
#include "UP_GPIO.h"
#include "UP_TIMER.h"

#define MAX_TIMERS 10 // 假设最大TIMER数量为10

typedef struct
{
    uint32_t timer;
    uint16_t channel;
    uint32_t period;
} TimerChannelPeriod;
// 定义结构体数组
TimerChannelPeriod timerChannelPeriods[] = {
    {TIMER0, TIMER_CH_0, 0},
    {TIMER0, TIMER_CH_1, 0},
    {TIMER0, TIMER_CH_2, 0},
    {TIMER0, TIMER_CH_3, 0},
    {TIMER1, TIMER_CH_0, 0},
    {TIMER1, TIMER_CH_1, 0},
    {TIMER1, TIMER_CH_2, 0},
    {TIMER1, TIMER_CH_3, 0},
    {TIMER2, TIMER_CH_0, 0},
    {TIMER2, TIMER_CH_1, 0},
    {TIMER2, TIMER_CH_2, 0},
    {TIMER2, TIMER_CH_3, 0},
    {TIMER3, TIMER_CH_0, 0},
    {TIMER3, TIMER_CH_1, 0},
    {TIMER3, TIMER_CH_2, 0},
    {TIMER3, TIMER_CH_3, 0},
    {TIMER4, TIMER_CH_0, 0},
    {TIMER4, TIMER_CH_1, 0},
    {TIMER4, TIMER_CH_2, 0},
    {TIMER4, TIMER_CH_3, 0},
    {TIMER7, TIMER_CH_0, 0},
    {TIMER7, TIMER_CH_1, 0},
    {TIMER7, TIMER_CH_2, 0},
    {TIMER7, TIMER_CH_3, 0},
    {TIMER8, TIMER_CH_0, 0},
    {TIMER8, TIMER_CH_1, 0},
    {TIMER9, TIMER_CH_0, 0},
    {TIMER10, TIMER_CH_0, 0},
    {TIMER11, TIMER_CH_0, 0},
    {TIMER11, TIMER_CH_1, 0},
    {TIMER12, TIMER_CH_0, 0},
    {TIMER13, TIMER_CH_0, 0},
};
// 设置不同TIMER下不同通道的period值
void setPeriod(uint32_t timer, uint16_t channel, uint32_t period)
{
    // 遍历数组，找到匹配的TIMER和通道，并更新period值
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timerChannelPeriods[i].timer == timer && timerChannelPeriods[i].channel == channel) {
            timerChannelPeriods[i].period = period;
            break;
        }
    }
}

// 获取不同TIMER下不同通道的period值
uint32_t getPeriod(uint32_t timer, uint16_t channel)
{
    // 遍历数组，找到匹配的TIMER和通道，并返回对应的period值
    for (int i = 0; i < MAX_TIMERS; i++) {
        if (timerChannelPeriods[i].timer == timer && timerChannelPeriods[i].channel == channel) {
            return timerChannelPeriods[i].period;
        }
    }

    // 如果没有找到匹配的TIMER和通道，返回默认值（例如0）
    return 0;
}

// 定义计算函数，将一个输入数字i，限定在start, end之间
uint32_t clamp(uint32_t i, uint32_t start, uint32_t end)
{
    if (i < start) {
        return start;
    } else if (i > end) {
        return end;
    }
    return i;
}

// uint32_t timers[]     = {TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TIMER9, TIMER10, TIMER11, TIMER12, TIMER13};
// uint32_t rcu_timers[] = {RCU_TIMER0, RCU_TIMER1, RCU_TIMER2, RCU_TIMER3, RCU_TIMER4, RCU_TIMER5, RCU_TIMER6, RCU_TIMER7, RCU_TIMER8, RCU_TIMER9, RCU_TIMER10, RCU_TIMER11, RCU_TIMER12, RCU_TIMER13};
/*!
    \brief PWM初始化，频率越大，PWM精度越低
    \param timer 定时器结构体
    \param frequency PWM频率
        \arg 范围50Hz - 1000 000Hz => 对应周期 20ms - 1μs
    \param pwm 初始化占空比
        \arg 范围0 - 10000 => 对应占空比 0% - 100%
*/
extern void PWM_init(UP_Timer timer, uint32_t frequency, uint32_t pwm)
{

    // -------------------------------------------配置GPIO复用功能
    GPIO_Init_AF(timer.uc_gpio, timer.alt_func_num);

    // -------------------------------------------配置定时器
    // rcu_periph_enum rcu_timer;
    // int len = sizeof(timers) / sizeof(timers[0]);
    // for (int i = 0; i < len; i++) {
    //     if (timers[i] == timer.timer_periph) {
    //         rcu_timer = rcu_timers[i];
    //         break;
    //     }
    // }

    UP_TIMER_PARAMS params;
    params.prescaler = 240U;
    params.frequency = frequency;
    params.period_ms = 0;
    TIMER_init_with_params(timer.timer_periph, params);

    timer_oc_parameter_struct timer_ocintpara;
    timer_ocintpara.ocpolarity  = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
    /* 输出结构体 */
    timer_channel_output_config(timer.timer_periph, timer.channel, &timer_ocintpara);

    // pwm输出模式
    timer_channel_output_mode_config(timer.timer_periph, timer.channel, TIMER_OC_MODE_PWM0);

    // 关闭shadow
    timer_channel_output_shadow_config(timer.timer_periph, timer.channel, TIMER_OC_SHADOW_DISABLE);

    // 自动重载shadow
    timer_auto_reload_shadow_enable(timer.timer_periph);

    // 如果使用timer0或timer7，需要进行enable
    // 	timer_primary_output_config(TIMER0, ENABLE);

    uint32_t period = ((SystemCoreClock / params.prescaler) / params.frequency);
    setPeriod(timer.timer_periph, timer.channel, period);
    // pwm输出脉冲值，如果周期的脉冲值为10000，则占空比为 6000/10000 = 60%
    uint32_t clamped_pwm = clamp(pwm, 0, 10000);
    uint32_t pulse = period * clamped_pwm / 10000;
    timer_channel_output_pulse_value_config(timer.timer_periph, timer.channel, pulse);
}

/*!
    \brief 更新PWM脉冲值
        channel output pulse value,0~65535
        \param[in] timer 定时器
        \param[in] pulse 脉冲值 占空比
            \arg 0-10000 -> 对应占空比 0% - 100%
*/
extern void PWM_update(UP_Timer timer, uint32_t pwm)
{
    // 根据timer.timer_periph获取定时器的period脉冲值
    uint32_t period = getPeriod(timer.timer_periph, timer.channel);

    // 0说明周期没有初始化，直接返回
    if (period == 0)
        return;

    uint32_t pulse = period * clamp(pwm, 0, 10000) / 10000;
    timer_channel_output_pulse_value_config(timer.timer_periph, timer.channel, pulse);
}